package com.rsscollector.controller.taglibs.app;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.el.ELException;
import javax.servlet.jsp.el.ExpressionEvaluator;
import javax.servlet.jsp.el.FunctionMapper;
import javax.servlet.jsp.el.VariableResolver;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class ELTagSupport extends SimpleTagSupport {

    private static Object evaluate(String expression,
                                   Class expectedType, JspContext jspContext)
            throws ELException {
        return evaluate(expression, expectedType,
                jspContext, null);
    }

    private static Object evaluate(String expression,
                                   Class expectedType, JspContext jspContext,
                                   FunctionMapper functionMapper)
            throws ELException {
        ExpressionEvaluator evaluator
                = jspContext.getExpressionEvaluator();
        VariableResolver variableResolver
                = jspContext.getVariableResolver();
        return evaluator.evaluate(
                expression, expectedType,
                variableResolver, functionMapper);
    }

    protected Object evaluate(String expression,
                              Class expectedType) throws ELException {
        return evaluate(expression, expectedType, getJspContext());
    }

    private Object queryPageContext(
            String name, Class expectedType) throws ELException {
        String expr = "${pageContext." + name + "}";
        return evaluate(expr, expectedType);
    }

    protected HttpServletRequest getRequest() throws ELException {
        Object request;
        JspContext jspContext = getJspContext();
        if (jspContext instanceof PageContext)
            request = ((PageContext) jspContext).getRequest();
        else
            request = queryPageContext("request",
                    HttpServletRequest.class);
        return (HttpServletRequest) request;
    }

    protected HttpServletResponse getResponse() throws ELException {
        Object response;
        JspContext jspContext = getJspContext();
        if (jspContext instanceof PageContext)
            response = ((PageContext) jspContext).getResponse();
        else
            response = queryPageContext("response",
                    HttpServletResponse.class);
        return (HttpServletResponse) response;
    }

    protected HttpSession getSession() throws ELException {
        Object session;
        JspContext jspContext = getJspContext();
        if (jspContext instanceof PageContext)
            session = ((PageContext) jspContext).getSession();
        else
            session = queryPageContext("session",
                    HttpSession.class);
        return (HttpSession) session;
    }

    protected ServletContext getApplication() throws ELException {
        Object application;
        JspContext jspContext = getJspContext();
        if (jspContext instanceof PageContext)
            application = ((PageContext) jspContext)
                    .getServletContext();
        else
            application = queryPageContext("servletContext",
                    ServletContext.class);
        return (ServletContext) application;
    }

}